package cn.song.service.impl;

import cn.song.Utils.KeyUtils;
import cn.song.convert.OrderMaster2OrderDto;
import cn.song.domain.OrderDetail;
import cn.song.domain.OrderMaster;
import cn.song.domain.ProductInfo;
import cn.song.dto.CardDto;
import cn.song.dto.OrderDto;
import cn.song.enums.OrderStatusEnum;
import cn.song.enums.PayStatusEnum;
import cn.song.enums.ResultEnum;
import cn.song.exceptions.SellException;
import cn.song.repository.OrderDetailRepository;
import cn.song.repository.OrderMasterRepository;
import cn.song.service.OrderService;
import cn.song.service.ProductService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Slf4j
public class OrderServiceImpl implements OrderService {

    @Resource
    private ProductService productService;

    @Resource
    private OrderDetailRepository orderDetailRepository;

    @Resource
    private OrderMasterRepository orderMasterRepository;



    @Override
    @Transactional
    public OrderDto createOrder(OrderDto orderDto) {
        // 创建订单编号
        String OrderDtoId = KeyUtils.getUniqeKey();
        BigDecimal amount = new BigDecimal(BigInteger.ZERO);
        //查询shangpin
        for(OrderDetail orderDetail :orderDto.getOrderDetails()){
            ProductInfo product = productService.findById(orderDetail.getProductId());
            if(product==null){
                throw new SellException(ResultEnum.PRODUCT_NOT_EXIST);
            }
            //计算总价
             amount = product.getProductPrice().multiply(new BigDecimal(orderDetail.getProductQuantity())).add(
                    amount
            );
            //订单详情入库
            orderDetail.setDetailId(KeyUtils.getUniqeKey());
            orderDetail.setOrderId(OrderDtoId);
            BeanUtils.copyProperties(product,orderDetail);
            orderDetailRepository.save(orderDetail);

        }
        //订单入库
        OrderMaster master = new OrderMaster();
        orderDto.setOrderId(OrderDtoId);
        BeanUtils.copyProperties(orderDto,master);
        master.setOrderAmount(amount);
        master.setOrderStatus(OrderStatusEnum.NEW.getCode());
        master.setPayStatus(PayStatusEnum.WAIT.getCode());

        orderMasterRepository.save(master);
        // 扣库存
        List<CardDto> cardDtoList = orderDto.getOrderDetails().stream().map(e -> new CardDto(e.getProductId(), e.getProductQuantity())).collect(
                Collectors.toList()
        );

        productService.decreaseStock(cardDtoList);


        return orderDto;
    }

    @Override
    public OrderDto findOne(String orderId) {

        OrderMaster order = orderMasterRepository.findOne(orderId);
        if(order==null){
            throw new SellException(ResultEnum.ORDERMASTER_NOT_EXIST);
        }
        List<OrderDetail> orderDetails = orderDetailRepository.findByOrderId(order.getOrderId());
        if(CollectionUtils.isEmpty(orderDetails)){
            throw  new SellException(ResultEnum.ORDERDETAILA_NOT_EXIST);
        }
        OrderDto orderDto = new OrderDto();
        BeanUtils.copyProperties(order,orderDto);
        orderDto.setOrderDetails(orderDetails);
        return orderDto;
    }

    @Override
    public Page<OrderDto> findList(String buyerOpenId, Pageable pageable) {
        Page<OrderMaster> orderMasters = orderMasterRepository.findByBuyerOpenid(buyerOpenId, pageable);
        List<OrderDto> orderDtos = OrderMaster2OrderDto.change(orderMasters.getContent());
        return new PageImpl<OrderDto>(orderDtos,pageable,orderMasters.getTotalElements());

    }

    @Override
    public OrderDto Cannel(OrderDto orderDto) {
        // 判断订单状态
        OrderMaster orderMaster = new OrderMaster();

        if (!orderDto.getOrderStatus().equals(OrderStatusEnum.NEW.getCode())) {
            log.error("【取消订单】订单状态不正确, orderId={}, orderStatus={}", orderDto.getOrderId(), orderDto.getOrderStatus());
            throw new SellException(ResultEnum.ORDER_STATUS_ERROR);
        }
        // 修改订单状态
        orderDto.setOrderStatus(OrderStatusEnum.CANCEL.getCode());
        BeanUtils.copyProperties(orderDto,orderMaster);
        OrderMaster updateResult = orderMasterRepository.save(orderMaster);
        if (updateResult == null) {
            log.error("【取消订单】更新失败, orderMaster={}", orderMaster);
            throw new SellException(ResultEnum.ORDER_UPDATE_FAIL);
        }

        //返回库存
        List<CardDto> cardDtos = orderDto.getOrderDetails().stream().map(e -> new CardDto(e.getProductId(), e.getProductQuantity())).collect(Collectors.toList());
        productService.increaseStock(cardDtos);


        //已支付 退款
        // TODO
        return orderDto;
    }

    @Override
    public OrderDto finish(OrderDto orderDto) {
        if(!orderDto.getOrderStatus().equals(OrderStatusEnum.NEW.getCode())){
            log.error("完结订单状态不正确, orderId is {} . orderStatus is {} .",orderDto.getOrderId(),orderDto.getOrderStatus()  );
            throw new SellException(ResultEnum.ORDER_STATUS_ERROR);
        }
        orderDto.setOrderStatus(OrderStatusEnum.FINISH.getCode());
        OrderMaster master = new OrderMaster();
        BeanUtils.copyProperties(orderDto,master);
        OrderMaster master1 = orderMasterRepository.save(master);
        if(master1==null){
            log.error("完结订单更新失败 orderMaster is {} .",master);
            throw new SellException(ResultEnum.ORDER_FINISH_FAIL);
        }
        return orderDto;
    }

    @Override
    public OrderDto paid(OrderDto orderDto) {
        // 判断订单状态
        if(!orderDto.getOrderStatus().equals(OrderStatusEnum.NEW.getCode())){
            log.error("订单状态不正确, orderId is {} . orderStatus is {} .",orderDto.getOrderId(),orderDto.getOrderStatus()  );
            throw new SellException(ResultEnum.ORDER_STATUS_ERROR);
        }
        // 判断支付状态
        if(!orderDto.getPayStatus().equals(PayStatusEnum.WAIT.getCode())){
            log.error("订单支付状态不正确, orderId is {} . status is {}.",orderDto.getOrderId(),orderDto.getPayStatus());
            throw  new SellException(ResultEnum.ORDER_PAYSTATUS_ERROR);
        }
        orderDto.setPayStatus(PayStatusEnum.SUCCESS.getCode());
        OrderMaster orderMaster = new OrderMaster();
        BeanUtils.copyProperties(orderDto,orderMaster);
        OrderMaster master = orderMasterRepository.save(orderMaster);
        if(master==null){
            log.error("订单支付状态更新失败,orderMaster is {}.",master);
            throw new SellException(ResultEnum.ORDER_PAYSTATUS_FAIL);
        }
        return orderDto;
    }
}
